package com.jichangxiu.framework.aspect;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.jichangxiu.common.annotation.DataScope;
import com.jichangxiu.common.constant.Constant;
import com.jichangxiu.common.entity.bo.SecurityUser;
import com.jichangxiu.common.entity.po.BaseEntity;
import com.jichangxiu.common.entity.vo.BaseQueryVo;
import com.jichangxiu.common.utils.SqlUtils;
import com.jichangxiu.common.utils.TokenUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * DataScopeAspect:
 *
 * @author Jcx
 * @create 2023-04-04 10:21
 */
@Slf4j
@Aspect
@Component
public class DataScopeAspect {

    @Resource
    private TokenUtils tokenUtils;

    /**
     * 数据权限过滤关键字
     */
    public static final String DATA_SCOPE = "dataScope";

    @Before("@annotation(dataScope)")
    public void doBefore(JoinPoint point, DataScope dataScope) {
        clearDataScope(point);
        handleDataScope(point, dataScope);
    }

    protected void handleDataScope(final JoinPoint joinPoint, DataScope dataScope) {
        // 获取当前的用户
        SecurityUser securityUser = tokenUtils.getSecurityUser();
        if (ObjectUtil.isNotEmpty(securityUser)) {
            // 如果是超级管理员，则不过滤数据
            if (ObjectUtil.isNotEmpty(securityUser) && !securityUser.getIsPlatform() && !Constant.PLATFORM_SUPER_USER.equals(securityUser.getUserCode())) {
                dataScopeFilter(joinPoint, securityUser, dataScope.deptAlias(), dataScope.userAlias());
            }
        }
    }

    /**
     * 数据范围过滤
     *
     * @param joinPoint    切点
     * @param securityUser 用户
     * @param deptAlias    部门别名
     * @param userAlias    用户别名
     */
    public static void dataScopeFilter(JoinPoint joinPoint, SecurityUser securityUser, String deptAlias, String userAlias) {
        String dataScope = SqlUtils.getDataScope(securityUser, deptAlias, userAlias);
        if (StrUtil.isNotEmpty(dataScope)) {
            Object params = joinPoint.getArgs()[0];
            if (ObjectUtil.isNotEmpty(params) && params instanceof BaseEntity) {
                BaseEntity baseEntity = (BaseEntity) params;
                baseEntity.getParams().put(DATA_SCOPE, " AND (" + dataScope + ")");
            }
            if (ObjectUtil.isNotEmpty(params) && params instanceof BaseQueryVo) {
                BaseQueryVo baseQueryVo = (BaseQueryVo) params;
                baseQueryVo.getParams().put(DATA_SCOPE, " AND (" + dataScope + ")");
            }
        }
    }

    /**
     * 拼接权限sql前先清空params.dataScope参数防止注入
     *
     * @param joinPoint 拦截器对象
     */
    private void clearDataScope(final JoinPoint joinPoint) {
        Object params = joinPoint.getArgs()[0];
        if (ObjectUtil.isNotEmpty(params) && params instanceof BaseEntity) {
            BaseEntity baseEntity = (BaseEntity) params;
            baseEntity.getParams().put(DATA_SCOPE, "");
        }
    }

}
